﻿using System;
using System.Text;
using System.Web.Caching;

namespace Bpms.Cache
{
    /// <summary>
    /// 默认缓存
    /// </summary>
    public class DefaultCache : ICacheStrategy
    {
        private static readonly DefaultCache instance = new DefaultCache();

        protected static volatile System.Web.Caching.Cache webCache = System.Web.HttpRuntime.Cache;

        private int _timeOut = 1440; // 默认缓存存活期为1440分钟(24小时)

        //private static object syncObj = new object();

        /// <summary>
        /// 建立回调委托的一个实例
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <param name="reason"></param>
        public void onRemove(string key, object val, CacheItemRemovedReason reason)
        {
            switch (reason)
            {
                case CacheItemRemovedReason.DependencyChanged:
                    break;
                case CacheItemRemovedReason.Expired:
                    {
                        break;
                    }
                case CacheItemRemovedReason.Removed:
                    {
                        break;
                    }
                case CacheItemRemovedReason.Underused:
                    {
                        break;
                    }
                default: break;
            }

            //使用缓存日志
            myLogger.WriteLog("Cache:[" + key + "] RemovedReason:[" + reason.ToString() + "]<br />");
        }

        /// <summary>
        /// 加入当前对象到缓存中
        /// </summary>
        /// <param name="objectId">对象的键值</param>
        /// <param name="objectValue">缓存的对象</param>
        public void AddObject(string objectId, object objectValue)
        {

            if (objectId == null || objectId.Length == 0 || objectValue == null)
            {
                return;
            }

            CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);

            if (TimeOut == 999999999)
            {
                webCache.Insert(objectId, objectValue, null, DateTime.MaxValue, TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, callBack);
            }
            else
            {
                webCache.Insert(objectId, objectValue, null, DateTime.Now.AddMinutes(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
            }
        }

        /// <summary>
        /// 加入当前对象到缓存中
        /// </summary>
        /// <param name="objId">对象的键值</param>
        /// <param name="o">缓存的对象</param>
        public void AddObjectWith(string objectId, object objectValue)
        {
            if (objectId == null || objectId.Length == 0 || objectValue == null)
            {
                return;
            }

            CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);

            webCache.Insert(objectId, objectValue, null, System.DateTime.Now.AddHours(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.High, callBack);
        }

        /// <summary>
        /// 加入当前对象到缓存中,并对相关文件建立依赖
        /// </summary>
        /// <param name="objId">对象的键值</param>
        /// <param name="o">缓存的对象</param>
        /// <param name="files">监视的路径文件</param>
        public void AddObjectWithFileChange(string objId, object o, string[] files)
        {
            if (objId == null || objId.Length == 0 || o == null)
            {
                return;
            }

            CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);

            CacheDependency dep = new CacheDependency(files, DateTime.Now);

            webCache.Insert(objId, o, dep, System.DateTime.Now.AddHours(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
        }

        /// <summary>
        /// 加入当前对象到缓存中,并使用依赖键
        /// </summary>
        /// <param name="objId">对象的键值</param>
        /// <param name="o">缓存的对象</param>
        /// <param name="dependKey">依赖关联的键值</param>
        public void AddObjectWithDepend(string objectId, object objectValue, string[] dependKey)
        {
            if (objectId == null || objectId.Length == 0 || objectValue == null)
            {
                return;
            }

            CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);

            CacheDependency dep = new CacheDependency(null, dependKey, DateTime.Now);

            webCache.Insert(objectId, objectValue, dep, System.DateTime.Now.AddMinutes(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
        }

        /// <summary>
        /// 删除缓存对象
        /// </summary>
        /// <param name="objectId">对象的关键字</param>
        public void RemoveObject(string objectId)
        {
            if (objectId == null || objectId.Length == 0)
            {
                return;
            }
            webCache.Remove(objectId);
        }

        /// <summary>
        /// 返回一个指定的对象
        /// </summary>
        /// <param name="objectId">对象的关键字</param>
        /// <returns>对象</returns>
        public object RetrieveObject(string objectId)
        {
            if (objectId == null || objectId.Length == 0)
            {
                return null;
            }

            return webCache.Get(objectId);
        }

        /// <summary>
        /// 设置到期相对时间[单位：／分钟] 
        /// </summary>
        public virtual int TimeOut
        {
            set
            {
                _timeOut = value > 0 ? value : 999999999;
            }
            get
            {
                return _timeOut > 0 ? _timeOut : 999999999;
            }
        }


        private Log.LogAdapter myLogger;
        public void Accept(Log.LogAdapter logger)
        {
            myLogger = logger;
        }


    }
}
